package base

import (
	"core/http"
	"core/routing"
	"fmt"
	NetHttp "net/http"
)

/**
 * 输入过滤器类型
 */
type InputFilter func(v interface{}) interface{}

/**
 * 应用结构体
 */
type Application struct {
	inputFilter    InputFilter
	uploadMaxLimit int64
	timezone       string
	resource       string
	router         *routing.Rtr
	request        *http.Req
	EnableTLS      bool
	Address        string
	Port           string
	certFile       string
	keyFile        string
	status         bool
}

var App *Application

/**
 * 初始化应用
 */
func init() {
	App = NewApp()
}

/**
 * 创建应用
 */
func NewApp() *Application {
	return new(Application)
}

/**
 * 设置上传的最大限制,单位B
 * @param limit int64
 */
func (app *Application) SetUploadMaxLimit(limit int64) {
	app.uploadMaxLimit = limit
}

/**
 * 返回上传的最大限制,单位B
 * @return int64
 */
func (app *Application) GetUploadMaxLimit() int64 {
	return app.uploadMaxLimit
}

/**
 * 设置数据过滤器
 * @param filter InputFilter
 */
func (app *Application) SetInputFilter(filter InputFilter) {
	app.inputFilter = filter
}

/**
 * 返回数据过滤器
 * @return InputFilter
 */
func (app *Application) GetInputFilter() InputFilter {
	return app.inputFilter
}

/**
 * 设置静态资源根路径
 * @param path string
 */
func (app *Application) SetResource(path string) {
	app.resource = path
}

/**
 * 返回静态资源根路径
 * @return string
 */
func (app *Application) GetResource() string {
	return app.resource
}

/**
 * 设置时区
 * @param timezone string
 */
func (app *Application) SetTimezone(timezone string) {
	app.timezone = timezone
}

/**
 * 返回时区
 * @return string
 */
func (app *Application) GetTimezone() string {
	return app.timezone
}

/**
 * 设置Server TLS证书
 * @param certFile string
 * @param keyFile string
 */
func (app *Application) SetTLSFile(certFile string, keyFile string) {
	app.certFile = certFile
	app.keyFile = keyFile
}

/**
 * 是否启用TLS
 * @param tls bool
 */
func (app *Application) EnabledTLS(tls bool) {
	app.EnableTLS = tls
}

/**
 * 返回请求对象
 * @return *http.Req
 */
func (app *Application) Request() *http.Req {
	return app.request
}

/**
 * 返回路由器
 * @return *routing.Rtr
 */
func (app *Application) Router() *routing.Rtr {

	if nil == app.router {
		app.router = routing.Router()
	}

	return app.router
}

/**
 * 请求处理
 * @param w http.ResponseWriter
 * @param r http.Request
 */
func (app *Application) ServeHTTP(w NetHttp.ResponseWriter, r *NetHttp.Request) {

	//初始化Request组件
	app.request = http.Request(r)

	_match := app.Router().Match(r)

	//未处理的404
	if nil == _match {
		w.WriteHeader(404)
		fmt.Fprint(w, "<h1>404 - Not Found!</h1>")
	}

	if _route, _ok := _match.(*routing.Route); true == _ok {
		w.WriteHeader(200)
		fmt.Fprint(w, _route.GetAction()(w, r))
	}

	//404路由
	if _action, _ok := _match.(routing.Action); true == _ok {
		w.WriteHeader(404)
		fmt.Fprint(w, _action(w, r))
	}
}

/**
 * 运行HTTP服务
 * @param addr string
 * @param port string
 */
func (app *Application) Serve(addr string, port string) {

	if true == app.status {
		return
	}

	app.status = true
	app.Address = addr
	app.Port = port

	server := &NetHttp.Server{Addr: addr + ":" + port, Handler: app}

	if true == app.EnableTLS {
		server.ListenAndServeTLS(app.certFile, app.keyFile)
	} else {
		server.ListenAndServe()
	}
}
